﻿//using DBUtil.Annotations;
//using DBUtil.Util;
//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Linq.Expressions;
//using System.Reflection;
//using System.Runtime.InteropServices.ComTypes;
//using System.Text;
//using System.Threading;

//namespace DBUtil.Builders
//{
//    /// <summary>
//    /// 默认Insert构建器
//    /// </summary>
//    /// <typeparam name="T"></typeparam>
//    public class DefaultInsertBuilder<T> : IInsertBuilder<T> where T : class, new()
//    {
//        private List<T> _datas = null;
//        private List<PropertyInfo> _props = null;
//        private Type _type = null;
//        private string _table = null;
//        private List<(string type, object data)> _commands = new List<(string type, object data)>();
//        private bool _hasBuild = false;
//        private readonly DBAccess db;
//        private List<(string tableName, Dictionary<string, object>)> _buildDatas = null;

//        /// <summary>
//        /// 根据DBAccess创建构建器实例
//        /// </summary>
//        /// <param name="db"></param>
//        public DefaultInsertBuilder(DBAccess db)
//        {
//            this.db = db;
//            _type = typeof(T);
//            _props = _type.GetProperties().ToList();
//        }

//        /// <summary>
//        /// 忽略指定的属性,如: builder.Ignore(model=>model.CreateTime)
//        /// </summary>
//        /// <param name="expression"></param>
//        /// <returns></returns>
//        public IInsertBuilder<T> Ignore(Expression<Func<T, object>> expression)
//        {
//            _commands.Add((nameof(Ignore), expression));
//            return this;
//        }

//        /// <summary>
//        /// 忽略所有的属性
//        /// </summary>
//        /// <returns></returns>
//        public IInsertBuilder<T> IgnoreAll()
//        {
//            _commands.Add((nameof(IgnoreAll), null));
//            return this;
//        }

//        /// <summary>
//        /// 指定插入的表名
//        /// </summary>
//        /// <param name="tableName"></param>
//        /// <returns></returns>
//        public IInsertBuilder<T> UseTable(string tableName)
//        {
//            if (!string.IsNullOrWhiteSpace(tableName)) _table = tableName;
//            return this;
//        }

//        /// <summary>
//        /// 插入数据并获取生成的Id
//        /// </summary>
//        /// <returns></returns>
//        public long InsertAndGetId()
//        {
//            return InsertAndGetIds().LastOrDefault();
//        }

//        /// <summary>
//        /// 插入数据并获取生成的id
//        /// </summary>
//        /// <returns></returns>
//        public List<long> InsertAndGetIds()
//        {
//            _build();
//            var ids = db.InsertBatchAndGetIds(_buildDatas);
//            return ids;
//        }



//        /// <summary>
//        /// 插入数据并根据查询构建器重新查询数据集合
//        /// </summary>
//        /// <param name="selectBuilder"></param>
//        /// <returns></returns>
//        public T InsertAndGetModel(Func<ISelectBuilder<T>, ISelectBuilder<T>> selectBuilder = null) => InsertAndGetModels(selectBuilder).FirstOrDefault();

//        private PropertyInfo _getIdentityPropery()
//        {
//            for (int i = 0; i < _props.Count; i++)
//            {
//                var key = _props[i].GetCustomAttribute<KeyAttribute>();
//                if (key != null && key.KeyType == EnumKeyType.Identity) return _props[i];
//            }
//            return null;

//        }

//        /// <summary>
//        /// 插入数据并根据查询构建器重新查询数据集合
//        /// </summary>
//        /// <param name="selectBuilder"></param>
//        /// <returns></returns>
//        public List<T> InsertAndGetModels(Func<ISelectBuilder<T>, ISelectBuilder<T>> selectBuilder = null)
//        {
//            var prop = _getIdentityPropery();
//            if (prop != null)
//            {
//                var ids = InsertAndGetIds();
//                for (int i = 0; i < ids.Count && i < _datas.Count; i++)
//                {
//                    prop.SetValue(_datas[i], ids[i]);
//                }
//            }
//            else
//            {
//                InsertAffectRows();
//            }
//            return _datas;
//        }

//        /// <summary>
//        /// 指定插入的属性(将属性的值直接拼接到Sql语句中)
//        /// </summary>
//        /// <param name="expression"></param>
//        /// <returns></returns>
//        public IInsertBuilder<T> ValueRaw(Expression<Func<T, object>> expression)
//        {
//            _commands.Add((nameof(ValueRaw), expression));
//            return this;
//        }

//        /// <summary>
//        /// 使用模型数据
//        /// </summary>
//        /// <param name="models"></param>
//        /// <returns></returns>
//        public IInsertBuilder<T> UseModelData(params T[] models)
//        {
//            _datas = models.ToList();
//            return this;
//        }

//        /// <summary>
//        /// 指定插入的属性
//        /// </summary>
//        /// <param name="expression"></param>
//        /// <returns></returns>
//        public IInsertBuilder<T> Value(Expression<Func<T, object>> expression)
//        {
//            _commands.Add((nameof(Value), expression));
//            return this;
//        }

//        private void _build()
//        {
//            if (_hasBuild) throw new Exception($"不能重复构建{nameof(DefaultInsertBuilder<T>)}");
//            //检测是否设置了模型数据
//            if (_datas == null) throw new Exception("必须传入要操作的数据模型!");

//            //首先获取表名
//            if (string.IsNullOrWhiteSpace(_table))
//            {
//                var attr = _type.GetCustomAttribute<TableAttribute>();
//                if (attr == null || string.IsNullOrWhiteSpace(attr.Name))
//                {
//                    _table = _type.Name;
//                }
//                else
//                {
//                    _table = attr.Name;
//                }
//            }
//            //获取要插入的列名和值
//            var index = _commands.FindLastIndex(c => c.type == nameof(IgnoreAll));
//            //model: 0 按注解,1 强制忽略,2 强制引入,3 强制原生引入
//            var fetchRules = new List<(string propName, int model)>();
//            //初始化提取规则
//            foreach (var prop in _props)
//            {
//                fetchRules.Add((prop.Name, 0));
//            }
//            //按顺序处理命令先合并command
//            for (int i = 0; i < _commands.Count; i++)
//            {
//                var command = _commands[i];
//                if (command.type == nameof(IgnoreAll))
//                {
//                    for (int m = 0; m < fetchRules.Count; m++)
//                    {
//                        var item = fetchRules[m];
//                        fetchRules.RemoveAt(m);
//                        fetchRules.Insert(m, (item.propName, 1));
//                    }
//                }
//                else
//                {
//                    var expression = command.data as Expression<Func<T, object>>;
//                    var names = ExpressionUtil.GetMemberName<T>(expression);
//                    for (int j = 0; j < names.Count; j++)
//                    {
//                        var index2 = fetchRules.FindIndex(item => item.propName == names[j]);
//                        if (index2 >= 0)
//                        {
//                            fetchRules.RemoveAt(index2);
//                        }
//                        var model = 0;
//                        if (command.type == nameof(Ignore))
//                        {
//                            model = 1;
//                        }
//                        else if (command.type == nameof(Value))
//                        {
//                            model = 2;
//                        }
//                        else if (command.type == nameof(ValueRaw))
//                        {
//                            model = 3;
//                        }
//                        fetchRules.Add((names[j], model));
//                    }
//                }
//            }
//            //根据合并的命令去从模型中提取数据
//            _buildDatas = _fetchDatas(fetchRules);
//            _hasBuild = true;
//        }

//        private List<(string tableName, Dictionary<string, object> dic)> _fetchDatas(List<(string propName, int model)> fetchRules)
//        {
//            var res = new List<(string tableName, Dictionary<string, object> dic)>();
//            for (int i = 0; i < _props.Count; i++)
//            {
//                var prop = _props[i];
//                var propname = prop.Name;
//                var rule = fetchRules.Find(item => item.propName == propname);
//                //强制忽略
//                if (rule.model == 1) continue;
//                //主键信息
//                var key = prop.GetCustomAttribute<KeyAttribute>();
//                var isKey = key != null;
//                //判断引入的类型:原生引用,参数化引用
//                var isPara = true;
//                if (rule.model == 3)
//                {
//                    isPara = false;
//                }
//                else if (rule.model == 2)
//                {
//                    isPara = true;
//                }
//                else if (rule.model == 0)
//                {
//                    //跳过 [NotMapped]
//                    var isNotMapper = prop.GetCustomAttribute<NotMappedAttribute>() != null;
//                    if (isNotMapper) continue;
//                    //主键自增列自动忽略
//                    if (isKey && key.KeyType == EnumKeyType.Identity) continue;
//                    //判断是否使用sql直接拼接
//                    isPara = prop.GetCustomAttribute<RawValueAttribute>() == null;
//                }
//                //变为集合操作
//                var batch = _datas;
//                for (int j = 0; j < batch.Count; j++)
//                {
//                    var (colname, colvalue) = _getPropValue(prop, batch[j]);
//                    if (isKey)
//                    {
//                        if (key.KeyType == EnumKeyType.DistributeId)
//                        {
//                            colvalue = db.GeneratorDistribute.NewId(db.DBConn + "_" + _table + "_" + colname);
//                            prop.SetValue(batch[j], colvalue);
//                        }
//                        else if (key.KeyType == EnumKeyType.GenerateIdByDBCache)
//                        {
//                            colvalue = db.NewId(_table, colname);
//                            prop.SetValue(batch[j], colvalue);
//                        }
//                        else if (key.KeyType == EnumKeyType.GenerateIdByProcessCache)
//                        {
//                            colvalue = db.GeneratorProcessCache.NewId(db.DBConn, _table, colname);
//                            prop.SetValue(batch[j], colvalue);
//                        }
//                        else if (key.KeyType == EnumKeyType.Guid)
//                        {
//                            colvalue = Guid.NewGuid().ToString();
//                            prop.SetValue(batch[j], colvalue);
//                        }
//                    }
//                    Dictionary<string, object> dic = null;
//                    if (res.Count == j)
//                    {
//                        dic = new Dictionary<string, object>();
//                        res.Add((_table, dic));
//                    }
//                    else
//                    {
//                        dic = res[j].dic;
//                    }
//                    if (isPara) dic.Add(colname, colvalue);
//                    else dic.Add(colname, (colvalue, true));
//                }
//            }
//            return res;
//        }

//        private (string colName, object value) _getPropValue(PropertyInfo prop, object inst)
//        {
//            //获取列名
//            var col = "";
//            var colAttr = prop.GetCustomAttribute<ColumnAttribute>();
//            if (colAttr == null || string.IsNullOrWhiteSpace(colAttr.Name))
//            {
//                col = prop.Name;
//            }
//            else
//            {
//                col = colAttr.Name;
//            }
//            //获取值
//            object value = prop.GetValue(inst);
//            return (col, value);
//        }

//        /// <summary>
//        /// 插入数据并返回受影响的行数
//        /// </summary>
//        /// <returns></returns>
//        public int InsertAffectRows()
//        {
//            _build();
//            return db.InsertBatch(_buildDatas);
//        }
//    }
//}
